package org.phalanx.gwt.client;

import java.util.Date;

import org.phalanx.gwt.client.constants.PhalanxPagenameConstants;
import org.phalanx.gwt.client.shared.AuthenticationListener;
import org.phalanx.gwt.client.shared.AuthenticationManager;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class PhalanxLoginSequence implements EntryPoint, KeyPressHandler, AuthenticationListener, ValueChangeHandler<Boolean> {
	private VerticalPanel mainPanel = new VerticalPanel();
	private HorizontalPanel userPanel = new HorizontalPanel();
	private HorizontalPanel passPanel = new HorizontalPanel();
	private HorizontalPanel buttonPanel = new HorizontalPanel();
	private Button loginButton = new Button("Login");
	private TextBox userField = new TextBox();
	private Label userLabel = new Label("Username: ");
	private Label passLabel = new Label("Password: ");
	private Label errorLabel = new Label();
	private HorizontalPanel errorPanel = new HorizontalPanel();
	private PasswordTextBox passField = new PasswordTextBox();
	private CheckBox saveUsername = new CheckBox("Remember Me");
	private boolean firstLoad = true;
	private boolean rememberMe = false;
	private AuthenticationManager auth;
	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		// On loading this module, lets first check if the user has a cookie
		// that allows them to automatically log in. If so we can jump directly to
		// the Phalanx Game client. If there is no valid login, we fail silently
		// and load the rest of the page.
		auth = new AuthenticationManager(this);
		
		attemptByPassLogin();
		checkForRememberCookie();
		
		loginButton.addStyleName("login");
		mainPanel.addStyleName("mainPanel");
		

		userPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		passPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		errorPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		mainPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		
		errorLabel.addStyleName("errortext");
		
		errorPanel.add(errorLabel);
		
		userPanel.add(userLabel);
		userPanel.add(userField);
		
		passPanel.add(passLabel);
		passPanel.add(passField);
		
		buttonPanel.add(saveUsername);
		buttonPanel.add(loginButton);
		
		mainPanel.add(userPanel);
		mainPanel.add(passPanel);
		mainPanel.add(buttonPanel);
		mainPanel.add(errorPanel);
		
		RootPanel.get("loginContainer").add(mainPanel);

		// Add the nameField and sendButton to the RootPanel
		// Use RootPanel.get() to get the entire body element
		//RootPanel.get("nameFieldContainer").add(nameField);
		//RootPanel.get("sendButtonContainer").add(sendButton);

		// Focus the cursor on the name field when the app loads
		userField.setFocus(true);;
		saveUsername.addValueChangeHandler(this);
		
		userField.addKeyPressHandler(this);
		passField.addKeyPressHandler(this);
		
		loginButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				auth.sendLoginRequest(userField.getText(), passField.getText());
			}
		});
	}
	
	private void attemptByPassLogin(){
		auth.sendLoginRequest();
	}
	
	public void setErrorText(String error){
		this.errorLabel.setText(error);
	}

	@Override
	public void onKeyPress(KeyPressEvent event) {
		if (event.getCharCode() == KeyCodes.KEY_ENTER) {
			auth.sendLoginRequest(userField.getText(), passField.getText());
		}
	}

	@Override
	public void authCallBack(boolean isLoggedIn, Integer status) {
		if (isLoggedIn){
			if (rememberMe){
				this.setRememberCookie();
			}
			Window.Location.assign(GWT.getHostPageBaseURL() + PhalanxPagenameConstants.MAIN_WEB_CLIENT);
		}else {
			if (!firstLoad){
				setErrorText("Invalid Login");
				passField.selectAll();
				passField.setFocus(true);
			}else {
				firstLoad = false;
			}
		}
	}
	
	private void setRememberCookie(){
		Cookies.setCookie("_rUser", userField.getText(),new Date(new Date().getTime() + 1209600000L)); // 2 week cookie
	}
	
	private void killRememberCookie(){
		if (Cookies.getCookie("_rUser") != null){
			Cookies.removeCookie("_rUser");
		}
	}
	
	private void checkForRememberCookie(){
		String rememberCookie = Cookies.getCookie("_rUser");
		
		if (rememberCookie != null){
			userField.setText(rememberCookie);
			saveUsername.setValue(true);
			rememberMe = true;
		}
	}

	@Override
	public void onValueChange(ValueChangeEvent<Boolean> event) {
		if (event.getSource().equals(saveUsername)){
			if (saveUsername.getValue()){
				this.rememberMe = true;
			}else {
				killRememberCookie();
				this.rememberMe = false;
			}
		}
	}
}
